package com.gopay.webtest.controller.expay;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.StopWatch;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.gopay.webtest.controller.base.BaseController;
import com.gopay.webtest.util.BaseSign;
import com.gopay.webtest.util.HttpClientUtil;
import com.gopay.webtest.util.ReflectUtil;
import com.gopay.webtest.vo.CommonResp;
import com.gopay.webtest.vo.ExPayApiConfirmInfo;
import com.gopay.webtest.vo.ExPayApiInfo;
import com.gopay.webtest.vo.ExPayCacheMock;
import com.gopay.webtest.vo.PayInfo;
import com.gopay.webtest.xml.XmlDao;

import net.sf.json.JSONObject;

/**
 * 快捷 代扣API支付（新）
 * @ExPayNewController.java
 * @author dongdh
 * @2016年7月13日 上午9:29:27  www.gopay.com.cn Inc.All rights reserved.
 */
@Controller
@RequestMapping("/expaynew")
public class ExPayNewController extends BaseController {

    private static final String CHARSET_GBK = "1";
    
    @Resource(name = "paySignHandler")
    private BaseSign paySignHandler;
    
    private static Map<String, String> map = null;
    
    @Autowired
    public ExPayNewController(@Qualifier(value = "xmlDao") XmlDao xmlDao) {
        try {
            map = xmlDao.readData4Map("expay_api", "payapply");
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 跳转到首页面
     * @param flag
     * @return
     */
    @RequestMapping("/api")
    public ModelAndView pay(String flag) {
        ModelAndView mav = new ModelAndView();
        PayInfo payinfo = getDefaultInfoFromXML();
        mav.setViewName("gopay.webtest.expaynew.api");
        if (StringUtils.equals(flag, "dk")) {
            //跳转到代扣页面
            mav.setViewName("gopay.webtest.expaynew.dk");
        }
        mav.addObject("payInfo", payinfo);
        return mav;
    } 
    
    /**
     * 跳转到 等待页面
     * @param orderId
     * @return
     */
    @RequestMapping("/payWait")
    public ModelAndView payWait() {
        
        ModelAndView mav = new ModelAndView();
        mav.setViewName("gopay.webtest.expaynew.apiPayWait");
        //mav.addObject("orderId", orderId);
        return mav;
    }
    
    /**
     * 获取订单返回结果.
     * @param orderId
     * @return
     */
    @ResponseBody
    @RequestMapping("/getOrderResult")
    public String getOrderResult(String orderId) {
        CommonResp payinfo = (CommonResp) ExPayCacheMock.getObject(orderId);
        JSONObject json = new JSONObject();
        if (payinfo != null) {
            ///表明已经有通知了
            logger.info("respCode ==" + payinfo.getRespCode());
            if (payinfo.getRespCode() != null && payinfo.getRespCode().equals("0000")) {
                json.put("result", "1");
                return "1";
            } else {
                json.put("result", "2");
                //错误 --删不删缓存.....
                //return json.toString();
                return "2";
            }
        } else {
            json.put("result", "0"); //2失败   1 成功   0未获取到
        }
        logger.info("orderId=" + orderId + ",获取返回结果=" + json.getString("result"));
        
        return json.getString("result");
    }
    
    /**
     * 跳转到确认支付页面
     * @param payInfo
     * @return
     */
    @RequestMapping(value = "/apiConfirm")
    public ModelAndView apiConfirm(ExPayApiInfo payInfo) {
        
        ModelAndView mav = new ModelAndView();
        
        payInfo.setGopayServerTime(com.gopay.webtest.util.DateUtils.date2string(new Date(), com.gopay.webtest.util.DateUtils.DEFAULT_PATTERN));
        
        /*if (StringUtils.equals(payInfo.getTranCode(), "8803")) {
           // mav.setViewName("gopay.webtest.expay.dkConfirm");
        } else {
            
        }*/
        mav.setViewName("gopay.webtest.expaynew.apiConfirm");
        mav.addObject("payInfo", payInfo);
        
        return mav;
    }
    
    /**
     * 确认支付 ajax调用
     * @param payInfo
     * @return
     */
   // @ResponseBody
    @RequestMapping(value = "/apiConfirmSubmit")
    public ModelAndView paySubmitConfirm(ExPayApiConfirmInfo payInfo, HttpServletRequest request) {
        
        // 设置MD5加密字段
        try {
            paySignHandler.sign(payInfo.getTranCode() + "_" + payInfo.getVersion(), "signType", "signValue", payInfo, request);
            logger.info("8802 快捷api 密文值:" + payInfo.getSignValue());
        } catch (Exception e) {
            e.printStackTrace();
        }
      //封装参数
        Map<String, String> paramMap = new HashMap<>();
        
        desField(payInfo, paramMap, payInfo.getVerficationCode());
        
        /*String xml = getXml(payInfo.getCharset(), paramMap, request);
        
      //解析返回的xml文件
        
        JSONObject js = new JSONObject();
        
        try {
            Document doc  = DocumentHelper.parseText(xml);
            
            Node el = doc.selectSingleNode("/GopayTranRes/respCode");
            
            String respCode = el.getStringValue();
            js.put("respCode", respCode);
            if (!"0000".equals(respCode)) {
                el = doc.selectSingleNode("/GopayTranRes/respMessage");
                js.put("respMessage", el.getStringValue());
            }
            
            js.put("xml", xml);
            
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return js.toString();*/
        ModelAndView mv = new ModelAndView();
        if (!payInfo.getCharset().equals("2")) {
            mv.setViewName("gopay.webtest.expaynew.formsubmit8802gbk");
        } else {
            mv.setViewName("gopay.webtest.expaynew.formsubmit8802utf8");
        }
        mv.addObject("payInfo", payInfo);
        
        return mv;
        
    }
    
    /**
     * 快捷api第一次提交
     * @param payInfo
     * @param request
     * @return
     */
   // @ResponseBody
    @RequestMapping(value = "/apiSubmit")
    public ModelAndView paySubmit(ExPayApiInfo payInfo, HttpServletRequest request) {

        String backgroundMerUrl = payInfo.getBackgroundMerUrl();
        if (backgroundMerUrl != null && !backgroundMerUrl.equals("")) {
            backgroundMerUrl = backgroundMerUrl + "?id=" + payInfo.getVerficationCode();
        }
        payInfo.setBackgroundMerUrl(backgroundMerUrl);
        StopWatch sw  = new StopWatch();
        
        // 设置MD5加密字段
        try {
            sw.start();
            paySignHandler.sign(payInfo.getTranCode() + "_" + payInfo.getVersion(), "signType", "signValue", payInfo, request);
            sw.stop();
            logger.info("step1 time:"+sw.getTime());
            logger.info("密文值:" + payInfo.getSignValue());
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        //封装参数
        Map<String, String> paramMap = new HashMap<>();
        
        desField(payInfo, paramMap, payInfo.getVerficationCode());
        
        ModelAndView mv = new ModelAndView();
        if (StringUtils.equals(payInfo.getTranCode(), "8803")) {
            paramMap.remove("cvn2");
            paramMap.remove("creditCardExpired");
            paramMap.remove("tranIP");
            paramMap.remove("bankCardType");
            
            if (!payInfo.getCharset().equals("2")) {
                mv.setViewName("gopay.webtest.expaynew.formsubmit8803gbk");
            } else {
                mv.setViewName("gopay.webtest.expaynew.formsubmit8803utf8");
            }
        } else if (StringUtils.equals(payInfo.getTranCode(), "8801")) {
            if (!payInfo.getCharset().equals("2")) {
                mv.setViewName("gopay.webtest.expaynew.formsubmit8801gbk");
            } else {
                mv.setViewName("gopay.webtest.expaynew.formsubmit8801utf8");
            }
        } else {
            throw new RuntimeException("无效交易码");
        }
        mv.addObject("payInfo", payInfo);
        
        return mv;
    }
    
    /**
     * 获取xml接待字符串.
     * @param xpath
     * @param doc
     * @return
     */
    private String getNodeStr(String xpath , Document doc) {
        Node node = doc.selectSingleNode(xpath);
        if (node != null) {
            return node.getStringValue();
        }
        return "";
    }
    
    /**
     * 加密字段.
     * @param info
     * @param paramMap
     * @param vcode
     */
    private void desField(Object info, Map<String, String> paramMap, String vcode) {
        
        try {
            //字段加密
            ReflectUtil.desField(info, vcode);
            ReflectUtil.copyFiledToMap(info, paramMap);
            paramMap.remove("verficationCode");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 获取返回 
     * @param cs
     * @param paramMap
     * @param request
     * @return
     */
    private String getXml(String cs, Map<String, String> paramMap, HttpServletRequest request) {
        
        logger.info("http 提交参数map==" + paramMap);
        
        String urlName = (String) request.getSession().getAttribute("gopay_webtest_URL_Name");
        String url = "";
        Map<String, String> urlMap = (Map<String, String>) request.getSession().getAttribute("gopay_webtest_URL");
        
        if ("自定义".equals(urlName)) {
           url = urlMap.get("dom"); 
        } else {
            url = urlMap.get("dom") + urlMap.get("expay");
        }
        logger.info("url===============>>>" + url);
        
        String postUrl = url;
        //发送http post请求
        String charset = "UTF-8";
        if (!cs.equals("2")) {
            //gbk
            charset = "GBK";
        }
        
        String xml =  HttpClientUtil.sendPostRequest(postUrl, paramMap, charset, charset);
        logger.info("返回xml==>" + xml);
        
        return xml;
    }
    
    private PayInfo getDefaultInfoFromXML() {
        PayInfo payInfo = new PayInfo();

        payInfo.setMerchantID((String) map.get("merchantID"));
        payInfo.setBackgroundMerUrl((String) map.get("backgroundMerURL"));
        payInfo.setCurrencyType((String) map.get("currType"));
        payInfo.setMerURL((String) map.get("merURL"));
        payInfo.setTranDateTime(com.gopay.webtest.util.DateUtils.date2string(new Date(), com.gopay.webtest.util.DateUtils.DEFAULT_PATTERN));
        payInfo.setTranIP((String) map.get("tranIP"));
        payInfo.setVirCardNoIn((String) map.get("virCardNoIn"));

        return payInfo;
    } 
}
